﻿using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using ProdService;

namespace UI.Filters
{
    public class EndDbContext : ActionFilterAttribute, IExceptionFilter
    {
        private DbContext dbContext;
        public EndDbContext(DbContext context)
        {
            this.dbContext = context;
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            dbContext.SaveChanges();
            doTransaction(t => t.Commit());

            base.OnResultExecuted(filterContext);
        }

        public void OnException(ExceptionContext filterContext)
        {
            doTransaction(t => t.Rollback());
        }

        private void doTransaction(Action<IDbContextTransaction> handle)
        {
            ///Note: 为什么不using dbContext？
            ///1、没有必要：依赖注入容器会完成Dispose()的工作
            ///2、页面中子Action错误会抛出给父Action，导致多次调用Rollback()，如果dbContext之前被Dispose()，
            ///   试图获取CurrentTransaction会继续报错，覆盖本来的错误信息

            using (var transaction = dbContext.Database.CurrentTransaction)
            {
                if (transaction != null)
                {
                    handle(transaction);
                }//比如LogOff，因为没有用到过dbContext，所以没有transaction
            }

        }
    }
}
